#include <ti/devices/msp432p4xx/driverlib/driverlib.h>
#include <stdint.h>
#include <stdbool.h>

// 按键定义
#define S1_PORT      GPIO_PORT_P1
#define S1_PIN       GPIO_PIN1
#define S2_PORT      GPIO_PORT_P1
#define S2_PIN       GPIO_PIN4

// LED定义
#define LED1_PORT    GPIO_PORT_P1
#define LED1_PIN     GPIO_PIN0
#define LED2_PORT    GPIO_PORT_P1
#define LED2_PIN     GPIO_PIN5

// 左电机控制引脚
#define MOTOR1_EN    GPIO_PIN7  // P3.7
#define MOTOR1_DIR   GPIO_PIN7  // P1.7
#define MOTOR1_PWM   GPIO_PIN7  // P2.7

// 右电机控制引脚
#define MOTOR2_EN    GPIO_PIN6  // P3.6
#define MOTOR2_DIR   GPIO_PIN6  // P1.6
#define MOTOR2_PWM   GPIO_PIN6  // P2.6

//pwm波形配置
#define EXTEND_PWM   GPIO_PIN4  // P2.4

/*SMCLK默认设置为12Mhz*/

// PWM配置 (100Hz)
#define PWM_PERIOD   10000       // SMCLK(12M)/100Hz
#define DUTY_M1      5000       // 50%占空比 (320/640)
#define DUTY_M2      3000       // 33%占空比 (192/640)

// 状态枚举
typedef enum {
    MOTOR_STOP =0 ,
    MOTOR_FORWARD,
    MOTOR_REVERSE
} MotorState;

// 全局变量
volatile uint32_t tickCount = 0;
volatile uint32_t s1PressTime = 0;
volatile uint32_t s2PressTime = 0;
volatile MotorState motor1State = MOTOR_STOP;
volatile MotorState motor2State = MOTOR_STOP;

// 函数声明
void initClock(void);
void initGPIO(void);
void initPWM(void);
void setMotor1(MotorState state);
void setMotor2(MotorState state);
void handleS1Press(void);
void handleS1Release(void);
void handleS2Press(void);
void handleS2Release(void);
bool isButtonPressed(uint8_t port, uint8_t pin);
void delayMs(uint32_t ms);
void setMotor1Duty(uint16_t percent);
void setMotor2Duty(uint16_t percent);

int main(void) {
    // 停止看门狗
    MAP_WDT_A_holdTimer();

    //初始化
    initGPIO();
    initPWM();

    // 初始状态：LED1亮，LED2灭，电机关闭
    MAP_GPIO_setOutputHighOnPin(LED1_PORT, LED1_PIN);
    MAP_GPIO_setOutputLowOnPin(LED2_PORT, LED2_PIN);
    setMotor1(MOTOR_STOP);
    setMotor2(MOTOR_STOP);


       while (1) {
           // === S1 控制 ===
           if (isButtonPressed(S1_PORT, S1_PIN) && GPIO_getInputPinValue(S2_PORT, S2_PIN) == GPIO_INPUT_PIN_HIGH) {
               delayMs(20); // 防抖
               if (isButtonPressed(S1_PORT, S1_PIN)) {
                   uint32_t pressDuration1 = 0;
                   handleS1Press();
                   while (isButtonPressed(S1_PORT, S1_PIN)){
                        delayMs(10);
                        pressDuration1 += 5;
                        if (pressDuration1 >= 300) { //长按三秒钟
                            setMotor1(MOTOR_STOP);

                   }

               }
           }
           }

           // === S2 控制 ===
           if (isButtonPressed(S2_PORT, S2_PIN)&& GPIO_getInputPinValue(S1_PORT, S1_PIN) == GPIO_INPUT_PIN_HIGH) {
               delayMs(20);
               if (isButtonPressed(S2_PORT, S2_PIN)) {
                   uint32_t pressDuration2 = 0;
                   handleS2Press();
                   while (isButtonPressed(S2_PORT, S2_PIN)){
                       delayMs(10);
                       pressDuration2 += 5;
                       if (pressDuration2 >= 300) {
                           setMotor2(MOTOR_STOP);

                     }
                 }

               }
           }
           //发挥部分P2.4输出PWM波形（频率100Hz，占空比50%）
            Timer_A_setCompareValue(TIMER_A0_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_2, DUTY_M1);

        }


}


void delayMs(uint32_t ms)
{
    uint32_t i;
    for(i = 0; i < (ms * 3000); i++) __nop();
}

bool isButtonPressed(uint8_t port, uint8_t pin)
{
    return GPIO_getInputPinValue(port, pin) == GPIO_INPUT_PIN_LOW;
}

// 初始化GPIO
void initGPIO(void) {
    // 配置LED引脚
    MAP_GPIO_setAsOutputPin(LED1_PORT, LED1_PIN);
    MAP_GPIO_setAsOutputPin(LED2_PORT, LED2_PIN);

    // 配置电机控制引脚
    MAP_GPIO_setAsOutputPin(GPIO_PORT_P3, MOTOR1_EN);
    MAP_GPIO_setAsOutputPin(GPIO_PORT_P1, MOTOR1_DIR);
    MAP_GPIO_setAsOutputPin(GPIO_PORT_P3, MOTOR2_EN);
    MAP_GPIO_setAsOutputPin(GPIO_PORT_P1, MOTOR2_DIR);

    // 配置按键引脚(上拉电阻)
    MAP_GPIO_setAsInputPinWithPullUpResistor(S1_PORT, S1_PIN);
    MAP_GPIO_setAsInputPinWithPullUpResistor(S2_PORT, S2_PIN);
}

// 初始化PWM
void initPWM(void) {
    // 配置PWM引脚
    MAP_GPIO_setAsPeripheralModuleFunctionOutputPin(
        GPIO_PORT_P2,
        MOTOR1_PWM | MOTOR2_PWM | EXTEND_PWM,
        GPIO_PRIMARY_MODULE_FUNCTION
    );//将指定 GPIO 引脚配置为外设模块的输出功能

    // 配置TimerA0 - 左电机(P2.7)
    Timer_A_PWMConfig pwmConfigLeft = { 
        .clockSource = TIMER_A_CLOCKSOURCE_SMCLK,                 // SMCLK作为时钟源
        .clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_12,
        .timerPeriod = PWM_PERIOD,                                //周期值
        .compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_4,     // CCR4
        .compareOutputMode = TIMER_A_OUTPUTMODE_RESET_SET,        // 复位/置位模式
        .dutyCycle = 0                                            // 初始关闭
    };
    MAP_Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfigLeft);

    // 配置TimerA0 - 右电机(P2.6)
    Timer_A_PWMConfig pwmConfigRight = {
        .clockSource = TIMER_A_CLOCKSOURCE_SMCLK,               // SMCLK作为时钟源
        .clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_12,
        .timerPeriod = PWM_PERIOD,                              //周期值
        .compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_3,   // CCR3
        .compareOutputMode = TIMER_A_OUTPUTMODE_RESET_SET,      // 复位/置位模式
        .dutyCycle = 0  // 初始关闭
    };
    MAP_Timer_A_generatePWM(TIMER_A0_BASE, &pwmConfigRight);
        
    //新增P2.4 PWM配置
    // 配置TimerA1 - P2.4（使用TimerA1以避免与电机PWM冲突）
    Timer_A_PWMConfig pwmConfigP24 = {
        .clockSource = TIMER_A_CLOCKSOURCE_SMCLK,               // 使用SMCLK时钟源
        .clockSourceDivider = TIMER_A_CLOCKSOURCE_DIVIDER_12,   //  12分频 (12MHz/12=1MHz)
        .timerPeriod = PWM_PERIOD,                              // 周期10000个计数
        .compareRegister = TIMER_A_CAPTURECOMPARE_REGISTER_2,   // 使用CCR2
        .compareOutputMode = TIMER_A_OUTPUTMODE_RESET_SET,      // 复位/置位模式
        .dutyCycle = 0                                          // 初始关闭
    };
    
    // 启动P2.4的PWM输出（使用TimerA1）
    MAP_Timer_A_generatePWM(TIMER_A1_BASE, &pwmConfigP24);
}

void setMotor1Duty(uint16_t percent)
{
    Timer_A_setCompareValue(TIMER_A0_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_4, PWM_PERIOD * percent / 100);
}
void setMotor2Duty(uint16_t percent)
{
    Timer_A_setCompareValue(TIMER_A0_BASE, TIMER_A_CAPTURECOMPARE_REGISTER_3, PWM_PERIOD * percent / 100);
}

// 设置左电机状态
void setMotor1(MotorState state) {
    motor1State = state;

    switch(state) {

        case MOTOR_STOP:
            MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P3, MOTOR1_EN);  // 禁用电机
            break;

        case MOTOR_FORWARD:
            MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P1, MOTOR1_DIR); // 正转方向
            setMotor1Duty(50);                                     // 设置PWM占空比
            MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P3, MOTOR1_EN); // 使能电机
            break;

        case MOTOR_REVERSE:
            MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P1, MOTOR1_DIR);  // 反转方向
            setMotor1Duty(50);                                     // 设置PWM占空比
            MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P3, MOTOR1_EN); // 使能电机
            break;
    }
}

// 设置右电机状态
void setMotor2(MotorState state) {
    motor2State = state;

    switch(state) {

        case MOTOR_STOP:
            MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P3, MOTOR2_EN);  // 禁用电机
            break;

        case MOTOR_FORWARD:
            MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P1, MOTOR2_DIR);  // 正转方向
            setMotor2Duty(50);                                      // 设置PWM占空比
            MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P3, MOTOR2_EN);   // 使能电机
            break;

        case MOTOR_REVERSE:
            MAP_GPIO_setOutputLowOnPin(GPIO_PORT_P1, MOTOR2_DIR);  // 反转方向
            setMotor2Duty(50);                                     // 设置PWM占空比
            MAP_GPIO_setOutputHighOnPin(GPIO_PORT_P3, MOTOR2_EN); // 使能电机
            break;
    }
}

// 处理S1按键按下
void handleS1Press(void) {

    if (motor1State == MOTOR_STOP || motor1State == MOTOR_REVERSE) {
        setMotor1(MOTOR_FORWARD);
    } else {
        setMotor1(MOTOR_REVERSE);
    }
}



// 处理S2按键按下
void handleS2Press(void) {

            if (motor2State == MOTOR_STOP || motor2State == MOTOR_REVERSE) {
            setMotor2(MOTOR_FORWARD);
        } else {
            setMotor2(MOTOR_REVERSE);
        }
}
